package com.itaem.community.modules.infrastructure.authority.service.role.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.itaem.community.core.exception.data.DataAlreadyExistsException;
import com.itaem.community.core.exception.data.NoSuchDataException;
import com.itaem.community.modules.infrastructure.authority.dto.role.RoleDTO;
import com.itaem.community.modules.infrastructure.authority.dto.role.RolePermissionLinkDTO;
import com.itaem.community.modules.infrastructure.authority.entity.permission.PermissionEntity;
import com.itaem.community.modules.infrastructure.authority.entity.role.RoleEntity;
import com.itaem.community.modules.infrastructure.authority.entity.role.RolePermissionEntity;
import com.itaem.community.modules.infrastructure.authority.mapper.permission.PermissionDAO;
import com.itaem.community.modules.infrastructure.authority.mapper.permission.PermissionTransformer;
import com.itaem.community.modules.infrastructure.authority.mapper.role.RoleDAO;
import com.itaem.community.modules.infrastructure.authority.mapper.role.RolePermissionDAO;
import com.itaem.community.modules.infrastructure.authority.mapper.role.RoleTransformer;
import com.itaem.community.modules.infrastructure.authority.service.role.RoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户角色表 服务实现类
 * </p>
 *
 * @author tomato
 * @since 2020-10-28
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleDAO, RoleEntity> implements RoleService {

    @Autowired
    private RoleDAO roleDAO;

    @Autowired
    private RoleTransformer roleTransformer;

    @Autowired
    private RolePermissionDAO rolePermissionDAO;

    @Autowired
    private PermissionDAO permissionDAO;

    @Autowired
    private PermissionTransformer permissionTransformer;

    @Override
    public RoleDTO findRoleById(Integer roleId) {
        // 创建查询
        LambdaQueryWrapper<RolePermissionEntity> target =
                new QueryWrapper<RolePermissionEntity>()
                        .lambda()
                        .select(RolePermissionEntity::getPermissionId)
                        .eq(RolePermissionEntity::getRoleId, roleId);
        if (rolePermissionDAO.selectCount(target) < 1) {
            // 没有权限绑定则直接返回基础信息
            RoleDTO dto = new RoleDTO();
            BeanUtils.copyProperties(
                    Optional.ofNullable(roleDAO.selectById(roleId))
                            .orElseThrow(() -> new NoSuchDataException("不存在指定角色")),
                    dto
            );
            return dto;
        }
        return roleTransformer.entityToDto(
                // 查询角色，如果角色不存在则抛出异常
                Optional.ofNullable(roleDAO.selectById(roleId)).orElseThrow(() -> new NoSuchDataException("不存在指定角色")),
                // 获取角色下所有权限
                permissionDAO.selectBatchIds(
                        rolePermissionDAO.selectList(target)
                                .stream()
                                .map(RolePermissionEntity::getPermissionId)
                                .collect(Collectors.toList())
                )
                        .stream()
                        // 实体转换
                        .map(permissionTransformer::entityToBriefDto)
                        .collect(Collectors.toList())
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addPermission(Integer roleId, @NotNull RolePermissionLinkDTO linkDto) {
        if (linkDto.getPermissionId() != null && rolePermissionDAO.selectCount(
                new QueryWrapper<RolePermissionEntity>()
                        .lambda()
                        .eq(RolePermissionEntity::getRoleId, roleId)
                        .eq(RolePermissionEntity::getPermissionId, linkDto.getPermissionId())
        ) != 0) {
            throw new DataAlreadyExistsException("该权限已添加到指定角色下!");
        }
        return SqlHelper.retBool(
                rolePermissionDAO.insert(
                        roleTransformer.toLinkEntity(
                                // 获取角色id
                                Optional.ofNullable(roleDAO.selectById(roleId))
                                        // 如果角色不存在则抛出异常
                                        .orElseThrow(() -> new NoSuchDataException("不存在此角色")),
                                // 获取权限id
                                Optional.ofNullable(permissionDAO.selectById(linkDto.getPermissionId()))
                                        .orElseGet(() -> {
                                            PermissionEntity permissionEntity = new PermissionEntity();
                                            permissionEntity.setContent(linkDto.getPermissionName());
                                            permissionEntity.setDeleted(Boolean.FALSE);
                                            permissionDAO.insert(permissionEntity);
                                            return permissionEntity;
                                        })
                        )
                )
        );


    }
}
